package com.zjs.db.sql.service;

import com.util.calculation.CalculateProgramTime;
import com.util.result.Message;
import com.zjs.db.sql.domain.SqlOrder;
import com.zjs.db.sql.domain.SqlUser;
import com.zjs.db.sql.mapper.SqlMapper;
import com.zjs.utils.NumberUtil;
import com.zjs.utils.UuidUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @Description SQL优化业务
 * @Author zhu_jinsheng[zhu_js@suixingpay.com]
 * @Date 2020/2/16 22:34
 * @Version 1.0
 */
@Slf4j
@Service
@Transactional
public class SqlServiceImpl {

    @Resource
    private SqlMapper mapper;

    /**
     * 随机生成姓名和性别
     *
     * @return
     */
    private SqlUser getNameAndSex() {
        //姓
        String[] surName = {"赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩",
            "杨", "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜",
            "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁",
            "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐", "费", "廉",
            "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常", "乐", "于", "时",
            "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹",
            "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧", "计", "伏", "成", "戴", "谈",
            "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "梁", "杜", "阮", "蓝", "闵", "席", "季"};
        //女孩名
        String girl = "秀娟英华慧巧美娜静淑惠珠翠雅芝玉萍红娥玲芬芳燕彩春菊兰凤洁梅琳素云莲真环雪荣爱妹霞香月莺"
            + "媛艳瑞凡佳嘉琼勤珍贞莉桂娣叶璧璐娅琦晶妍茜秋珊莎锦黛青倩婷姣婉娴瑾颖露瑶怡婵雁蓓纨仪荷丹蓉眉君"
            + "琴蕊薇菁梦岚苑婕馨瑗琰韵融园艺咏卿聪澜纯毓悦昭冰爽琬茗羽希宁欣飘育滢馥筠柔竹霭凝晓欢霄枫芸菲寒"
            + "伊亚宜可姬舒影荔枝思丽";
        //男孩名
        String boy = "伟刚勇毅俊峰强军平保东文辉力明永健世广志义兴良海山仁波宁贵福生龙元全国胜学祥才发武新利清飞"
            + "彬富顺信子杰涛昌成康星光天达安岩中茂进林有坚和彪博诚先敬震振壮会思群豪心邦承乐绍功松善厚庆磊民友"
            + "裕河哲江超浩亮政谦亨奇固之轮翰朗伯宏言若鸣朋斌梁栋维启克伦翔旭鹏泽晨辰士以建家致树炎德行时泰盛雄"
            + "琛钧冠策腾楠榕风航弘";
        SqlUser user = new SqlUser();
        //随机生成姓名和性别
        Random random = new Random();
        int index = random.nextInt(surName.length - 1);
        //获得一个随机的姓氏
        String name = surName[index];
        //可以根据这个数设置产生的男女比例
        int k = random.nextInt(3);
        if (k == 2) {
            int j = random.nextInt(girl.length() - 2);
            if (j % 2 == 0) {
                user.setUserName(name + girl.substring(j, j + 2));
                user.setUserSex(0);
            } else {
                user.setUserSex(0);
                user.setUserName(name + girl.substring(j, j + 1));
            }
        }
        else {
            int j = random.nextInt(boy.length() - 2);
            if (j % 2 == 0) {
                user.setUserSex(1);
                user.setUserName(name + boy.substring(j, j + 2));
            } else {
                user.setUserSex(1);
                user.setUserName(name + boy.substring(j, j + 1));
            }
        }
        return user;
    }

    /**
     * @Description: 随机生成省份
     * @Author: zhu_jinsheng[zhu_js@suixingpay.com]
     * @Date: 2020/2/17
     * @Param province
     * @return: java.lang.String
     */
    private String getProvince(String province) {
        //省份
        String[] allProvince = {"北京市", "天津市", "上海市", "重庆市", "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省",
            "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省", "河南省", "湖北省", "湖南省", "广东省", "海南省",
            "四川省", "贵州省", "云南省", "陕西省", "甘肃省", "青海省", "台湾省", "内蒙古自治区", "广西壮族自治区",
            "西藏自治区", "宁夏回族自治区", "新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区"};
        String[] provinces = allProvince;
        //判断是单个省份生成还是全部随机
        if (province != null && !province.equals("")) {
            //直接返回省份
            return province;
        }
        //随机生成省份
        Random random = new Random();
        int index = random.nextInt(provinces.length);
        //获得一个随机的省份
        String name = provinces[index];
        return name;
    }

    /**
     * @Description 专门生成单个的号码
     * @Author zhu_jinsheng[zhu_js@suixingpay.com]
     * @return: java.lang.String
     * @Date 2019/12/10 13:14
     */
    private String getPhoneNum() throws Exception {
        //给予真实的初始号段，号段是在百度上面查找的真实号段
        String[] start = {"133", "149", "153", "173", "177", "180", "181", "189", "199", "130", "131", "132",
            "145", "155", "156", "166", "171", "175", "176", "185", "186", "166", "134", "135", "136", "137",
            "178", "182", "183", "184", "187", "188", "198", "170", "171"};
        //随机出真实号段   使用数组的length属性，获得数组长度，
        //通过Math.random（）*数组长度获得数组下标，从而随机出前三位的号段
        String phoneFirstNum = start[(int) (Math.random() * start.length)];
        //随机出剩下的8位数
        String phoneLastNum = "";
        //定义尾号，尾号是8位
        final int phoneLen = 8;
        //循环剩下的位数
        for (int i = 0; i < phoneLen; i++) {
            //每次循环都从0~9挑选一个随机数
            phoneLastNum += (int) (Math.random() * 10);
        }
        //最终将号段和尾数连接起来
        String phoneNum = phoneFirstNum + phoneLastNum;
        //手机号密文加密
//        phoneNum = symmetricJiam.encrypt(phoneNum);
        return phoneNum;
    }

    /**
     * @Description 随机生成基本用户信息
     * @Author zhu_jinsheng[zhu_js@suixingpay.com]
     * @return: com.suixingpay.seckill.pojo.User
     * @Date 2019/12/10 11:49
     */
    private SqlUser randomUserInfo(String province) throws Exception {
        SqlUser user;
        //获取随机的姓名和性别
        user = getNameAndSex();
        //生成手机号
        user.setUserPhone(getPhoneNum());
        //初始化密码123456，通过密文加密
        user.setUserPassword("123456");
        //生成省份
        user.setUserProvince(getProvince(province));
        return user;
    }

    /**
     * @Description: 批量生成用户数据
     * @Author: zhu_jinsheng[zhu_js@suixingpay.com]
     * @Date: 2020/2/25
     * @Param num
     * @return: java.lang.String
     */
    public String createUserDate(int num) {
        CalculateProgramTime calculateProgramTime = new CalculateProgramTime();
        calculateProgramTime.setStartTime();
        try {
            int executeCount = 0;
            while (num > 0) {
                int insertCount = num - 1000 > 0 ? 1000 : num;
                List<SqlUser> dataList = new ArrayList<>();
                for (int i = 0; i < insertCount; i++) {
                    log.info("生成第{}条用户数据", ++executeCount);
                    //开始随机生成数据
                    SqlUser user = randomUserInfo("");
                    dataList.add(user);
                }
                num = num - mapper.insertUserDataByList(dataList);
            }
            calculateProgramTime.setEndTime();
            calculateProgramTime.printExecuteTime();
            return "生成用户数据成功";
        } catch (Exception e) {
            //记录日志
            log.error("【生成用户数据异常】{}", e);
            //异常事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return "生成用户数据失败";
        }
    }

    /**
     * 生成用户订单数据
     * @param userId 用户Id
     * @return
     */
    private SqlOrder randomOrderInfo(Integer userId) {
        SqlOrder sqlOrder = new SqlOrder();
        sqlOrder.setOrderNo(UuidUtil.get32Uuid());
        sqlOrder.setUserId(userId);
        sqlOrder.setOrderSource(NumberUtil.generateInt(0, 1));
        sqlOrder.setOrderTinype(NumberUtil.generateInt(0, 1));
        sqlOrder.setOrderSrvStatus(NumberUtil.generateInt(0, 7));
        sqlOrder.setOrderPayStatus(NumberUtil.generateInt(0, 2));
        sqlOrder.setOrderAuthAmt(new BigDecimal(NumberUtil.generateDouble(0.00, 2000.00)).setScale(2,BigDecimal.ROUND_HALF_UP));
        sqlOrder.setOrderPayAmt(new BigDecimal(NumberUtil.generateDouble(0.00, 2000.00)).setScale(2,BigDecimal.ROUND_HALF_UP));
        sqlOrder.setPayTime(new Date());
        sqlOrder.setUpdateTime(new Date());
        sqlOrder.setCreateTime(new Date());
        return sqlOrder;
    }

    /**
     * 通过用户id批量生成用户订单数据
     * @param num 生成订单数量
     * @param userId 用户Id
     * @return
     */
    public String createOrderDateByUserId(int num, Integer userId) {
        CalculateProgramTime calculateProgramTime = new CalculateProgramTime();
        calculateProgramTime.setStartTime();
        try {
            int executeCount = 0;
            while (num > 0) {
                int insertCount = num - 1000 > 0 ? 1000 : num;
                List<SqlOrder> dataList = new ArrayList<>();
                for (int i = 0; i < insertCount; i++) {
                    //开始随机生成数据
                    SqlOrder order = randomOrderInfo(userId);
                    dataList.add(order);
                    log.info("生成第{}条用户订单数据:{}", ++executeCount, order);
                }
                num = num - mapper.insertOrderDataByList(dataList);
            }
            calculateProgramTime.setEndTime();
            calculateProgramTime.printExecuteTime();
            log.info("【生成{}用户订单数据成功】", userId);
            return "生成用户订单数据成功";
        } catch (Exception e) {
            //记录日志
            log.error("【生成{}用户订单数据异常】{}", userId, e);
            //异常事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return "生成用户订单数据失败";
        }
    }

    /**
     * 通过订单号查询订单信息
     * @param orderNo
     * @return
     */
    public Message selectOrderByOrderNo(String orderNo) {
        SqlOrder sqlOrder = mapper.selectOrderByOrderNo(orderNo);
        return Message.success(sqlOrder);
    }
}
